//
// Created by jinling on 2025/6/25.
//
#include "FileLog.h"

using namespace tmms::base;

bool FileLog::Open(const std::string &filePath) {
        file_path_ =  filePath;
        //int  fd = ::open(file_path_.c_str() ,O_CREAT|O_APPEND|O_WRONLY,DEFFILEMODE);
        int fd = ::open(file_path_.c_str(), O_CREAT|O_APPEND|O_WRONLY, DEFFILEMODE);
        if (fd<0)
        {
                std::cout<<"open file faild, file path :"<<filePath<<std::endl;
                return false;
        }
        fd_=fd;
        return  true;
}

size_t FileLog::WriteLog(const std::string &msg)
{
        int  fd  = fd_ == -1 ? 1 :fd_;
        return ::write(fd,msg.data(),msg.size());
}

void FileLog::Rotate(const std::string &file)
{
        if(file_path_.empty())
        {
                return ;
        }
        int ret = :: rename(file_path_.c_str(), file.c_str());//先要把正在打印日志的文件改成新的文件名，是系统调用
        if (ret != 0 )
        {
                std::cerr<< "rename failed old :0"<< file_path_<<"new: "<<file;
        }
        int fd =::open(file_path_.c_str() ,O_CREAT|O_APPEND|O_WRONLY,DEFFILEMODE); // 在打开
        if (fd <0)
        {
                std::cout<<"open file log error.path "<<file << std::endl;
                return;
        }

        /*::dup2(fd, fd_) 是一个系统调用，用于复制文件描述符。它的作用是将文件描述符 fd 复制到另一个文件描述符 fd_，使得 fd_ 指向与 fd 相同的文件、管道或设备*/
        ::dup2(fd,fd_);
        /* 写和切分rotate  是可以在不同的线程中进行的 ，但是这个复制文件描述符的（dup2） 会把旧的(fd_)先关掉   那会不会在我的一个线程写的时候 会不会有一个线程把他关掉呢？
        不用担心， 当我的一个线程在写的时候，他Linux会自己锁住 inode，直到处理完成才会释放
        ===*/
        close(fd);
}

void FileLog::SetRotate (RotateType type)
{
        rotate_type_ = type;
}

RotateType FileLog::GetRotateType() const
{
        return rotate_type_;
}
int64_t FileLog::FileSize()const
{
        return ::lseek64(fd_,0,SEEK_END);
}
std::string FileLog::FilePath () const
{
        return file_path_;
}